package com.universest.swordholder.data.repository

import android.util.Log
import androidx.room.withTransaction
import com.universest.swordholder.data.UserDatabase
import com.universest.swordholder.data.dao.Volume
import com.universest.swordholder.data.dao.VolumeDao
import com.universest.swordholder.tools.getItemSwapped
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.firstOrNull

class VolumeRepository(val database: UserDatabase) {

    private val volumeDao: VolumeDao = database.volumeDao()

    fun getVolumeById(volumeId: Int): Flow<Volume?> {
        return volumeDao.getVolumeById(volumeId)
    }

    fun getAllVolumes(): Flow<List<Volume>> {
        return volumeDao.getAllVolumes()
    }

    // 新增方法
    fun getVolumeByBookId(bookId: Int): Flow<List<Volume>> {
        return volumeDao.getVolumeByBookId(bookId)
    }

    suspend fun insert(volume: Volume): Long {
        return volumeDao.insert(volume)
    }

    suspend fun update(volume: Volume) {
        volumeDao.update(volume)
    }

    suspend fun updateTransaction(volumes: List<Volume>, updater:(Int, Volume) -> Volume){
        database.withTransaction {
            try {
                volumes.forEachIndexed { index,it->
                    update(updater(index, it))
                }
            }catch (e: Exception){
                Log.e("volumeRepository", "updateTransaction error: $e")
            }
        }
    }

    suspend fun delete(volume: Volume) {
        volumeDao.delete(volume)
    }

    suspend fun deleteById(volumeId: Int) {
        volumeDao.deleteById(volumeId)
    }

    suspend fun deleteByBookId(bookId: Int) {
        volumeDao.deleteByBookId(bookId)
    }

    suspend fun swapVolumeOrder(volumeIdA: Int, volumeIdB: Int) {
        database.withTransaction {
            try {
                val volumeA = volumeDao.getVolumeById(volumeIdA).firstOrNull()
                val volumeB = volumeDao.getVolumeById(volumeIdB).firstOrNull()

                if (volumeA == null || volumeB == null) return@withTransaction
                if (volumeA.bookId != volumeB.bookId) return@withTransaction

                if (volumeA.order == volumeB.order) {
                    //兜底逻辑
                    val volumes = volumeDao.getAllVolumes().firstOrNull()
                    if(volumes == null){
                        return@withTransaction
                    }
                    volumes.getItemSwapped(volumes.indexOfFirst { it.volumeId == volumeIdA },
                        volumes.indexOfFirst { it.volumeId == volumeIdB })
                        .forEachIndexed {
                            index, it ->
                            volumeDao.update(it.copy(order = index*10+1))
                        }
                } else {
                    // 直接交换 order
                    volumeDao.update(volumeA.copy(order = volumeB.order))
                    volumeDao.update(volumeB.copy(order = volumeA.order))
                }
            } catch (e: Exception) {
                Log.e("volumeRepository", "swapvolumeOrder error: $e")
                throw e
            }
        }
    }
}
